package sf.database.mapper;

import sf.common.wrapper.Page;
import sf.core.DBObject;
import sf.database.dao.DBClient;
import sf.dynamicsql.mapper.DynmicSQLMapper;
import sf.jooq.mapper.JooqMapper;
import sf.querydsl.mapper.QueryDSLMapper;

import java.util.List;
import java.util.Map;

/**
 * 通用mapper类
 * @param <T>
 */
public interface DaoMapper<T extends DBObject> {
    /**
     * 合并记录
     * @param entity
     * @return
     */
    int merge(T entity);

    /**
     * 通用插入，插入一个实体对象到数据库,返回主键
     * @param entity 实体类
     * @return 返回插入的数量
     */
    int insert(T entity);


    /**
     * 批量插入实体,返回主键
     * @param list
     * @return 返回插入的总数
     */
    int[] insertBatch(List<T> list);

    /**
     * 批量插入实体,快速插入 不返回主键
     * @param list
     * @return 返回插入的总数
     */
    int[] insertBatchFast(List<T> list);

    /**
     * 根据主键更新对象,对象set过才被更新
     * @param entity 实体
     * @return 返回变更的总数
     */
    int updateById(T entity);

    /**
     * 更新
     * @param entity
     * @return
     */
    int update(T entity);

    /**
     * 批量更新
     * @param list
     * @return
     */
    int[] updateBatch(List<T> list);

    /**
     * 删除
     * @param entity
     * @return
     */
    int delete(T entity);

    /**
     * 根据主键删除对象，如果对象是复合主键，传入对象本生即可
     * @param key 主键
     * @return
     */
    int deleteById(Object... key);

    /**
     * 批量删除
     * @param entities
     * @return
     */
    int[] deleteInBatch(Iterable<T> entities);

    /**
     * 清空表
     */
    void deleteAllInBatch();

    /**
     * 逻辑删除
     * @param entity
     * @return
     */
    int logicDelete(T entity);

    /**
     * 逻辑删除对象，如果对象是复合主键，传入对象本生即可
     * @param key 主键
     * @return
     */
    int logicDeleteById(Object... key);

    /**
     * 根据主键获取对象，如果对象不存在，返回null
     * @param keys
     * @return
     */
    T unique(Object... keys);

    /**
     * 获取单一对象，如果对象不存在，返回null
     * @param query
     * @return
     */
    T single(T query);

    /**
     * 获取单一对象，如果在事物中执行会添加数据库行级锁(select * from table where id = ? for
     * update)，如果对象不存在，返回null
     * @param query
     * @return
     */
    T lock(T query);

    /**
     * 返回实体在数据库里的总数
     * @return
     */
    long count();

    /**
     * 根据条件查询数量
     * @param query
     * @return
     */
    long count(T query);

    /**
     * 是否存在,根据主键查询
     * @param id
     * @return
     */
    boolean existsById(Object... id);

    /**
     * 是否存在,根据对象查询
     * @param query
     * @return
     */
    boolean exists(T query);

    /**
     * 返回实体对应的所有数据库记录
     * @return
     */
    List<T> selectList(T query);

    /**
     * 返回实体对应的一个范围的记录
     * @param start
     * @param size
     * @return
     */
    Page<T> selectPage(T query, int start, int size);

    ////////////////////// sql 模板执行 //////////////////////

    /**
     * 执行一个jdbc sql模板查询
     * @param sql
     * @param paras
     * @return
     */
    List<T> selectTemplate(String sql, Map<String, Object> paras);

    /**
     * 执行一个更新的jdbc sql
     * @param sql
     * @param paras
     * @return
     */
    int executeTemplate(String sql, Map<String, Object> paras);

    //////////////////////////////////
    DynmicSQLMapper<T> getDynmicSQLMapper();

    //////////>>>>>>>>>>>>>>其他<<<<<<<<<<<<<<<<<<<
    JooqMapper<T> getJooqMapper();

    QueryDSLMapper<T> getQueryDSLMapper();
    //////////////////////////////////


    /**
     * @return
     */
    DBClient getDbClient();

    /**
     * @return
     */
    Class<T> getDomainClass();
}
